#include<iostream>
#include<string>
#include<regex>
int main()
{
    //std::string src="GET /bite/login?user=xiaoming&passwd=123456 HTTP/1.1\r\n";//这是http请求
    //std::regex reg("/nums/(\\d+)");//正则匹配规则regex,括号表示要提取，两个\\转义为单个.即"\d"用来表示数字，'+'表示一个或多个数字
    //std::regex reg("(GET|POST|DELETE|HEAD|PUT) (.*) (.*)");//这里的|就是‘或’的意思，'.'是一个通配符，可以匹配除了'\r'与'\n'以外的所有字符
    //'*'则表示可以匹配多个
    std::smatch s;//存储匹配上的字符串的容器容器

    std::string src="GET /bite/login?user=xiaoming&passwd=123456 HTTP/1.1\r\n";
    //std::regex reg("(GET|POST|DELETE|HEAD|PUT) ([^?]*).*");//[^?]表示匹配一个非‘？’的子符,'*'表示0或多个
    //由于'?'在表达式里有特殊含义，所以我们需要对'?'进行转义，单个'\'只是相当于对?进行转义后的那个值，所以我们要两个'\'，这样最终得到就是'\?'
    //std::regex reg("(GET|POST|DELETE|HEAD|PUT) ([^?]*)\\?(.*) (HTTP/1\\.[01])");//[01]表示0或者1,'[]'里面一次只匹配一个字符
    //最后的\r\n或\n通过|进行匹配,'|'只能在 ()里使用
    //同时在前面加'?:'则不会提取括号里的字符串，只是用于匹配
    //后面再给一个问号则前面括号里的内容是不确定的,匹配0次或1次
    //也就是说可以有？前面的字符进行匹配，也可以没有，这样我们请求报头的后缀就可以是'\n','\r\n',''这三种
    //(?:ab())这种格式，仅仅忽略最外层括号内部的其他元素，对于内部括号的捕获情况要看内部括号是怎么写的
    //可以这么理解，()就是要捕获，?:就是不捕获当前括号里的内容，括号里再加括号就是说明要捕获里面的内容
    std::regex reg("(GET|POST|DELETE|HEAD|PUT) ([^?]*)(?:\\?(.*))? (HTTP/1\\.[01])(?:\n|\r\n)?");

    bool ret=std::regex_match(src,s,reg);//最后会匹配上整个字符串，并且会将字符串与括号里面的东西一起放到容器里
    if(ret==false)
    {
        std::cout<<"没有匹配上"<<std::endl;
    }
    else
    {//顺序为先输出匹配上的，再输出括号里的
        for(auto& e:s)
            std::cout<<e<<std::endl;
    }
    return 0;
}